#!/Library/Frameworks/Python.framework/Versions/2.5/Resources/Python.app/Contents/MacOS/Python

import wx, sys, logging, datetime
import ConfigParser


def add_to_list(L): 
	"""decorator to be used with class methodlister.
    It adds the immediately following method/function 
    to the list of methods note that 'methods' is really 
    a class variable or a global variable in the module.
    I modded the class it works with to allow more than one 
    method list per class which allows us to keep discrete steps in the process
    listed in different lists. YOu could also use decorator
    outside of classes to sequence arbitrary lists of functions
    in a global list or lists.
    """
	def deco(func):        
		L.append(func)
		return func
	return deco

class methodlister(object):
	"""subclass this class to work 
    with methods from one or more more monolithc functions that need 
    to be dealt with as small bits for 'threading' purposes. Lets the
    logger log events with more granularity. Would allow a cancel or 
    perhaps an "undo" during login or or other user actions/sequences if we wanted...
    ...I think.
    """
	#methods = []  #one or more method-lists should be declared as class variables in the subclass


	def doall(self,list): 
		"""this executes all methods in a list in sequence. Error checking would be less
        useful this way, but might be worth doing in certain circumstances --basically
        would recreate the original monlithic function/method as a single call"""
		[func(self) for func in list]  


	#@add_to_list(methods)
		"""place this decorator with the target list ahead of each method you want listed
        """
	def donextmethod(self,list, index):      
		"""what the name says. keep track of the index at the caller level. 
        The index could be tracked internally as well if that would make things tidier in the code"""                                        
		list[index](self)

	def listerlen(self,list):
		"""Just returns the lenght of the specified list"""
		return len(list)

class LoggerTextCntl(wx.TextCtrl):
	def write(self, text):
		"""
        Write the text to the LoggerTextCntl instance
        If not called in the context of the gui thread then uses
        CallAfter to do the work there.
        """        

		if not wx.Thread_IsMain():
			wx.CallAfter(self.__write, text)
		else:
			self.__write(text)

	def __write(self, text):
		# helper function for actually writing the text.
		self.AppendText(text)

	def flush(self):
		pass


class TestFrame(wx.Frame):
	def __init__(self, parent, id, title):
		
		self.zapp = wx.GetApp()
		wx.Frame.__init__(self, parent, id, title, size=(1200, 700))
		self.avatarlist = []
		self.simlist = []
		self.ADlist = []
		panel = wx.Panel(self)
		self.timertext  = LoggerTextCntl(panel, -1, "",
										 style=wx.TE_MULTILINE|wx.TE_READONLY, size = (250,400))
		self.msgtext  = LoggerTextCntl(panel, -1, "",
									   style=wx.TE_MULTILINE|wx.TE_READONLY, pos = (251,0),size = (1049,400))
		self.errtext  = LoggerTextCntl(panel, -1, "",
									   style=wx.TE_MULTILINE|wx.TE_READONLY, pos = (251,401),size = (1049,200))
		self.login_button = wx.Button(panel, 1, 'Login', pos = (50, 623))
		

		self.avatar_combo = wx.ComboBox(panel, -1, pos=wx.Point(200, 620),
								  size=wx.Size(150, 150), choices=self.avatarlist, style = wx.CB_DROPDOWN, name = "avatar name")
		self.add_name_button = wx.Button(panel, 2, 'add name', pos = (351, 623))
		
		self.sim_combo = wx.ComboBox(panel, -1, pos=wx.Point(450, 620),
								  size=wx.Size(150, 150), choices=self.simlist, style = wx.CB_DROPDOWN, name = "Sim name")
		self.add_sim_button = wx.Button(panel, 3, 'add sim', pos = (651, 623))
		
		self.AD_combo = wx.ComboBox(panel, -1, pos=wx.Point(750, 620),
								  size=wx.Size(150, 150), choices=self.ADlist, style = wx.CB_DROPDOWN, name = "AD name")
		self.add_AD_button = wx.Button(panel, 4, 'add AD', pos = (901, 623))
		
		self.Bind(wx.EVT_BUTTON, self.OnLogin, id=1)
		self.Bind(wx.EVT_BUTTON, self.on_add_name_button, id=2)
		self.Bind(wx.EVT_BUTTON, self.on_add_sim_button, id=3)
		self.Bind(wx.EVT_BUTTON, self.on_add_AD_button, id=4)
		
		self.Centre()
		self.eqg = None
		self.gotimer =True
		self.timer = wx.Timer(self)

		self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
		self.Bind(wx.EVT_CLOSE, self.onCloseWindow)
		

		self.timer.Start(100)
		
		self.Show(True)
	def add_avatar_List(self, avatarlist, defaultavie):
		for index in range(len(avatarlist)):
			self.avatarlist.append(avatarlist[index][1])
			self.avatar_combo.Append(avatarlist[index][1])

		if not self.avatar_combo.SetStringSelection(defaultavie):
			if self.avatar_combo.GetCount() != 0:
				self.avatar_combo.SetSelection(0) 
				
	def add_sim_List(self, simlist, defaultsim):
		for index in range(len(simlist)):
			self.simlist.append(simlist[index][1])
			self.sim_combo.Append(simlist[index][1])

		if not self.sim_combo.SetStringSelection(defaultsim):
			if self.sim_combo.GetCount() != 0:
				self.sim_combo.SetSelection(0) 
				
	def add_AD_List(self, ADlist, defaultAD):
		for index in range(len(ADlist)):
			self.ADlist.append(ADlist[index][1])
			self.AD_combo.Append(ADlist[index][1])

		if not self.AD_combo.SetStringSelection(defaultAD):
			if self.AD_combo.GetCount() != 0:
				self.AD_combo.SetSelection(0) 
		
			

	def on_add_name_button(self,event):
		avatar_name = self.avatar_combo.GetValue()
		if (avatar_name not in self.avatarlist) and (avatar_name != ""):
			self.avatarlist.append(avatar_name)
			self.avatar_combo.Append(avatar_name)
		self.zapp.avatar_name = avatar_name
		
	def on_add_sim_button(self,event):
		sim_name = self.sim_combo.GetValue()
		if (sim_name not in self.simlist) and (sim_name != ""):
			self.simlist.append(sim_name)
			self.sim_combo.Append(sim_name)
		self.zapp.sim_name = sim_name

	def on_add_AD_button(self,event):
		AD_name = self.AD_combo.GetValue()
		if (AD_name not in self.ADlist) and (AD_name != ""):
			self.ADlist.append(AD_name)
			self.AD_combo.Append(AD_name)
		self.zapp.AD_name = AD_name

	def OnTimer(self, event):
		self.zapp.DoTimer(event)
		
	def OnLogin(self, event):

		if self.gotimer == True:
			self.timer.Stop()
			print self.avatarlist
			print self.simlist
			print self.ADlist

			self.gotimer = False
		else:
			self.timer.Start(100)
			self.gotimer = True

	def onCloseWindow(self,event):
		#self.timer.Stop()
		#self.eqg.contenew = False
		#wx.GetApp().avatar_obj.tearDown()
		#sys.stdout = sys.stderr = wx.GetApp().savedstdio
		#i = 0
		#while i<20:
			#print i
			#print self.eqg
			#if not self.eqg.isAlive():break
			#time.sleep(1)
			#i +=1
		
		self.zapp.cleanup()
		logging.shutdown()
		self.Destroy()

		


class TestApp(wx.App):
	def OnInit(self):
		
		self.savedstdio = sys.stdout

		self.loginmethodindex=0
		self.place_avatarindex=0
		
		
		self.frame = TestFrame(None, -1, "TestIt")
		self.Load_Config_file()
		sys.stdout = sys.stderr = self.frame.errtext
		
		self.frame.Show(True)

		
		#logging setup could go here instead...

		self.SetTopWindow(self.frame)
		self.avatar_name = ""
		self.AD_name = ""
		self.sim_name = ""
		#registration.init()           #ZCA stuff?




		return True
	def cleanup(self):


		self.Save_Config_file()
		
		pass
		
	def DoTimer(self,event):


		if self.loginmethodindex==0: 

			#self.avatar_obj = avatar_obj(self)   #instantiate the avatar_obj class for login/place goodness

			#self.loginmethodslen = self.avatar_obj.listerlen(self.avatar_obj.loginmethods) #get the method list lengths
			#self.place_avatarmethodslen = self.avatar_obj.listerlen(self.avatar_obj.place_avatarmethods)

			##probably logging init code belongs in app __init__ code but oh well...

			console = logging.StreamHandler(self.frame.timertext)

			self.timerlogger = logging.getLogger("Timer")
			self.timerlogger.setLevel(logging.DEBUG)
			self.timerlogger.addHandler(console)
			self.logger = logging.getLogger("pyogp.lib.base.wxexample")
			self.loginmethodindex+=1

			#self.startedUDPhandler = False
			#self.udpcounter = 0    #to limit UDP packets for testing purposes. Otherwise rig a "break" from while loop




		#if self.loginmethodindex <self.loginmethodslen:   #Start login methods sequence

			#self.avatar_obj.donextmethod(self.avatar_obj.loginmethods,self.loginmethodindex)  
			#self.loginmethodindex +=1


		#elif self.place_avatarindex <self.place_avatarmethodslen:   #start place avatar methods sequence
			#self.avatar_obj.donextmethod(self.avatar_obj.place_avatarmethods,self.place_avatarindex)  
			#self.place_avatarindex +=1


		#elif self.startedUDPhandler == False:             #start UDP packet handler sequence
			#self.avatar_obj.set_up_sim_presence()
			#self.avatar_obj.start_sim_EQG_thread()
			#self.startedUDPhandler = True

		#elif self.udpcounter<10:   # Go UDP packet handler GO!!!!
			#self.logger.info( "udp packet#: " + str(self.udpcounter) + ". Packet name is: " + str(self.avatar_obj.maintain_sim_presence()))
			#self.udpcounter+=1
		#elif self.udpcounter == 10:   #it done....
			#self.logger.info( "OMG did it work???")
			#self.udpcounter+=1



		self.timerlogger.info(  "time = " + str(datetime.datetime.now().microsecond) + " " 
								+ str(self.avatar_name) + " "
								+ str(self.sim_name) + " "
								+ str(self.AD_name))           

	def Load_Config_file(self):
		console = logging.StreamHandler(self.frame.msgtext)
		self.configlogger = logging.getLogger("Configgerer")
		self.configlogger.setLevel(logging.DEBUG)
		self.configlogger.addHandler(console)
		
		self.config = ConfigParser.SafeConfigParser()
		try:
			fp = open('wx_testconfig.cfg')
		except:
			try:
				fp = open('wx_testconfig.cfg','w')
			except: 
				self.configlogger.debug("could not create file!!!" ) 
			finally:
				fp.close()
				fp = open('wx_testconfig.cfg')

		self.config.readfp(fp)
		
		configlist = self.config.sections()
		self.configlogger.info("config sections = " + str(configlist))
		for sections in configlist:
			self.configlogger.info("section  = " + sections)
			itemslist = self.config.items(sections)
			for items in itemslist:
				self.configlogger.info("config items = " + str(items))
				
		if "avatar names list" not in configlist:
			self.configlogger.info("avatar names list does not exist! Adding..." )
			self.config.add_section("avatar names list")
		if not self.config.has_section(	"default avatar"):
			self.configlogger.info("default avatar list does not exist! Adding..." )
			self.config.add_section("default avatar")
		
			
		self.avatar_names_List = self.config.items("avatar names list")
		print self.avatar_names_List
		if  self.config.has_option(	"default avatar", "name"):
			self.default_avie = self.config.get("default avatar","name")
		else:
			self.default_avie = ""
			
		self.frame.add_avatar_List(self.avatar_names_List,self.default_avie)
			
		



		
		if "AD List" not in configlist:
			self.configlogger.info("AD List does not exist! Adding..." )
			self.config.add_section("AD List")
		if not self.config.has_section(	"default AD"):
			self.configlogger.info("default AD does not exist! Adding..." )
			self.config.add_section("default AD")
			
					
		self.AD_List = self.config.items("AD List")
		
		print self.AD_List
		if  self.config.has_option(	"default AD", "name"):
			self.default_AD = self.config.get("default AD","name")
		else:
			self.default_AD = ""
			
		self.frame.add_AD_List(self.AD_List,self.default_AD)
			
		if "sim List" not in configlist:
			self.configlogger.info("sim List does not exist! Adding..." )
			self.config.add_section("sim List")
		if not self.config.has_section(	"default sim"):
			self.configlogger.info("default sim does not exist! Adding..." )
			self.config.add_section("default sim")			
			
		self.sim_List = self.config.items("sim List")
		
		print self.sim_List
		if  self.config.has_option(	"default Sim", "name"):
			self.default_sim = self.config.get("default sim","name")
		else:
			self.default_sim = ""

		self.frame.add_sim_List(self.sim_List,self.default_sim)
		
		
			
	def Save_Config_file(self):
		
		self.default_avie = self.frame.avatar_combo.GetValue()
		self.default_sim = self.frame.sim_combo.GetValue()
		self.default_AD = self.frame.AD_combo.GetValue()
		
		self.avatar_names_list = self.frame.avatarlist
		self.sim_list = self.frame.simlist
		self.AD_list = self.frame.ADlist
		
		

		print self.avatar_names_list
		for index in range(len(self.avatar_names_list)):
			self.config.set("avatar names list", "name" +str(index), self.avatar_names_list[index])
		if self.default_avie != "" and self.default_avie  in self.avatar_names_list:
			self.config.set("default avatar","name", self.default_avie)
			

		for index in range(len(self.sim_list)):
			self.config.set("sim List", "name" +str(index), self.sim_list[index])
		if self.default_sim != "" and self.default_sim  in self.sim_list:
			self.config.set("default sim","name", self.default_sim)
			

		for index in range(len(self.AD_list)):
			self.config.set("AD List", "name" +str(index), self.AD_list[index])
		if self.default_AD != "" and self.default_AD  in self.AD_list:
			self.config.set("default AD","name", self.default_AD)
			
		
		fp = open('wx_testconfig.cfg', 'w')
		self.config.write(fp)

		



def wxtestmain():

	app = TestApp(None)

	app.MainLoop()

	return


def main():
	return wxtestmain()

if __name__=="__main__":
	main()
